/*
 * TimerControl.h
 *
 *  Created on: Jun 18, 2012
 *      Author: john
 */

#ifndef TIMERCONTROL_H_
#define TIMERCONTROL_H_

class TimerControl
{
	public:
		/*
		 * Constructor for the timer control class
		 *  - timer_no: from Arduino.h timer list
		 */
		TimerControl(uint8_t timer_no);

		/*
		 * set the A and B control registers
		 */
		void setControl(
				uint8_t out_mode_A,
				uint8_t out_mode_B,
				uint8_t timer_mode,
				uint8_t clock_select);

		/*
		 * Sets forceOutputCompare values in the control registers.
		 *
		 * This should be no-op'ed by deriving classes for timers that
		 * do not support this feature.
		 */
		virtual void forceOutputCompare(uint8_t a_or_b);

		/*
		 * Resets the timer counter to zero.
		 */
		void resetCounter();

		/*
		 * Sets the timer's OCRA value.
		 */
		void setOCRAValue(uint8_t val);

		/*
		 * Sets the timer's OCRB value.
		 */
		void setOCRBValue(uint8_t val);

		/*
		 * Sets the Input Capture Noise Canceller bit in control register B
		 *
		 * This should be no-op'ed by deriving classes for timers that
		 * do not support this feature.
		 */
		virtual void enableInputCompareNoiceCanceller(uint8_t enable);
		/*
		 * Sets the Input Capture Edge Select bit in control register B
		 *
		 * Param: rising_or_falling
		 * 	1 = rising edge
		 * 	0 = falling edge
		 *
		 * This should be no-op'ed by deriving classes for timers that
		 * do not support this feature.
		 */
		virtual void setInputCaptureEdgeSelect(uint8_t rising_or_falling);

		/*
		 * Disables the timer by setting the ChipSelect bits in control
		 * register B to zero.
		 */
		void disable();

		/*
		 * Sets the control registers to all the desired values.  This is
		 * only required after a disable command, if no other changes are
		 * desired.  It will use the retained values to re-enable the timer.
		 */
		void reenable();

		/*
		 * Sets all the interrupt flags, by default all are reset.
		 */
		void setInterruptFlags(uint8_t value=0xFF);

		/*
		 * disables all the INterrupt masks, by default, all are cleared.
		 */
		void setInterruptsMasks(uint8_t value=0x00);

		virtual ~TimerControl()
		{
			disable();
		}
	private:

		virtual void setAddresses() = 0;

		uint8_t timer_number;
		uint8_t saved_TCCRnA;
		uint8_t saved_TCCRnB;

		uint8_t TCCRnA_addr;
		uint8_t TCCRnB_addr;
		uint8_t OCRnA_addr;
		uint8_t OCRnB_addr;
		uint8_t TCNTn_addr;
		uint8_t TIFRn_addr;
		uint8_t TIMSKn_addr;


};

#endif /* TIMERCONTROL_H_ */
